package com.usc.mock.db.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.usc.mock.db.bean.CartInfo;
import com.usc.mock.db.bean.SkuInfo;
import com.usc.mock.db.bean.UserInfo;
import com.usc.mock.db.constant.GmallConstant;
import com.usc.mock.db.mapper.CartInfoMapper;
import com.usc.mock.db.service.CartInfoService;
import com.usc.mock.db.service.SkuInfoService;
import com.usc.mock.db.service.UserInfoService;
import com.usc.mock.utlil.ParamUtil;
import com.usc.mock.utlil.RandomBox;
import com.usc.mock.utlil.RandomCollection;
import com.usc.mock.utlil.RandomNum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * <p>
 * 购物车表 用户登录系统时更新冗余 服务实现类
 * </p>
 */
@Service
@Slf4j
public class CartInfoServiceImpl extends ServiceImpl<CartInfoMapper, CartInfo> implements CartInfoService {
    @Autowired
    SkuInfoService skuInfoService;

    @Autowired
    UserInfoService userInfoService;


    @Value("${mock.cart.user-rate:50}")
    String cartUserRate;

    @Value("${mock.cart.max-sku-count:8}")
    String maxSkuCount;

    @Value("${mock.cart.max-sku-num:3}")
    String maxSkuNum;

    @Value("${mock.date}")
    String mockDate;

    @Value("${mock.cart.source-type-rate}")
    String sourceTypeRate;

    @Value("10")
    String addCartRate;
    @Value("10")
    String delCartRate;

    public void genCartInfo(boolean ifClear) {

        ArrayList<Object> objects = new ArrayList<>();
        for (Iterator<Object> iterator = objects.iterator(); iterator.hasNext(); ) {
            Object next = iterator.next();

        }

        Date date = ParamUtil.checkDate(mockDate);
        RandomBox cartUserRateDice = new RandomBox(this.cartUserRate);

        if (ifClear) {
            remove(new QueryWrapper<>());
        }
        List<SkuInfo> skuInfoList = skuInfoService.list(new QueryWrapper<SkuInfo>());

        List<UserInfo> userInfoList = userInfoService.list(new QueryWrapper<>());
        List<CartInfo> cartInfoExistsList = this.list(new QueryWrapper<>());

        List<CartInfo> cartInfoList = new ArrayList<>();
        HashSet<String> userIdAndSkuIdSet = new HashSet<>();
        for (UserInfo userInfo : userInfoList) {
            if (cartUserRateDice.getRandBoolValue()) {
                int skuCount = RandomNum.getRandInt(1, ParamUtil.checkCount(maxSkuCount));
                Set skuSet = new HashSet();
                for (int i = 1; i <= skuCount; i++) {
                    int skuIndex = RandomNum.getRandInt(0, skuInfoList.size() - 1);
                    boolean noExists = skuSet.add(skuIndex);
                    if (noExists) {
                        SkuInfo skuInfo = skuInfoList.get(skuIndex);
                        CartInfo cartInfo = initCartInfo(skuInfo, userInfo.getId(), date);
                        cartInfo = checkAndMergeCart(cartInfo, cartInfoExistsList);
                        cartInfoList.add(cartInfo);

                    }

                }

            }
        }


        log.warn("共生成购物车" + cartInfoList.size() + "条");
        saveOrUpdateBatch(cartInfoList, 100);

        changeCartList();

    }

    private void changeCartList() {

        List<CartInfo> allCartInfoList = this.list(new QueryWrapper<CartInfo>().eq("is_ordered", "0"));
        Integer delCartRateNum = ParamUtil.checkRatioNum(delCartRate);
        Integer delCartNum = (delCartRateNum / 100) * allCartInfoList.size();
        List delIdList = new ArrayList();
        for (int i = 0; i < delCartNum; i++) {
            CartInfo cartInfo = RandomCollection.getOneFrom(allCartInfoList);
            allCartInfoList.remove(cartInfo);
            delIdList.add(cartInfo.getId());
        }
        this.removeByIds(delIdList);

        Integer addCartRateNum = ParamUtil.checkRatioNum(addCartRate);
        Integer addCartNum = (addCartRateNum * 100) / allCartInfoList.size() / 100;
        for (int i = 0; i < addCartNum; i++) {
            CartInfo cartInfo = RandomCollection.getOneFrom(allCartInfoList);
            cartInfo.setSkuNum(cartInfo.getSkuNum() + RandomNum.getRandInt(1, 2));
        }
        this.saveOrUpdateBatch(allCartInfoList, 100);
    }

    private CartInfo checkAndMergeCart(CartInfo cartInfo, List<CartInfo> cartInfoExistsList) {
        for (CartInfo cartInfoExists : cartInfoExistsList) {
            if (cartInfo.getUserId().equals(cartInfoExists.getUserId()) && cartInfo.getSkuId().equals(cartInfoExists.getSkuId())) {
                cartInfoExists.setSkuNum(cartInfo.getSkuNum() + cartInfoExists.getSkuNum());
                return cartInfoExists;
            }
        }
        return cartInfo;
    }

    public CartInfo initCartInfo(SkuInfo skuInfo, Long userId, Date date) {
        Integer skuCount = ParamUtil.checkCount(maxSkuNum);

        Integer[] sourceTypeRateArray = ParamUtil.checkRate(this.sourceTypeRate, 4);
        RandomBox sourceTypeGroup = RandomBox.builder().add(GmallConstant.SOURCE_TYPE_QUREY, sourceTypeRateArray[0])
                .add(GmallConstant.SOURCE_TYPE_PROMOTION, sourceTypeRateArray[1])
                .add(GmallConstant.SOURCE_TYPE_AUTO_RECOMMEND, sourceTypeRateArray[2])
                .add(GmallConstant.SOURCE_TYPE_ACTIVITY, sourceTypeRateArray[3]).build();
        String sourceType = sourceTypeGroup.getRandStringValue();


        CartInfo cartInfo = new CartInfo();
        cartInfo.setCartPrice(skuInfo.getPrice());
        cartInfo.setImgUrl(skuInfo.getSkuDefaultImg());
        cartInfo.setSkuId(skuInfo.getId());
        cartInfo.setSkuName(skuInfo.getSkuName());
        cartInfo.setUserId(userId);
        cartInfo.setIsOrdered(0);
        cartInfo.setSkuNum(RandomNum.getRandInt(1, skuCount) + 0L);
        cartInfo.setCreateTime(date);
        cartInfo.setSourceType(sourceType);
        if (sourceType.equals(GmallConstant.SOURCE_TYPE_PROMOTION)) {
            cartInfo.setSourceId(RandomNum.getRandInt(10, 100) + 0L);
        } else if (sourceType.equals(GmallConstant.SOURCE_TYPE_ACTIVITY)) {
            cartInfo.setSourceId(RandomNum.getRandInt(1, 2) + 0L);
        }

        return cartInfo;
    }


}
